# ifndef __CPtr_H_
# define __CPtr_H_

template <typename T>
class CCPtr;

template <typename T>
class CCounted {
  protected:
	CCounted () : m_lRefs (1) {}

  private:
	long m_lRefs;

	void AddRef () {::InterlockedIncrement (& m_lRefs);}
	bool Release () {return ::InterlockedDecrement (& m_lRefs) == 0;}

	friend class CCPtr<T>;
};

template <typename T>
class CCPtr {
	T * m_p;

  public:
	CCPtr () : m_p (NULL) {}
	CCPtr (T * _p) : m_p (_p) {}
	CCPtr (const CCPtr<T> & _other) : m_p (_other.m_p) {if (m_p) m_p->AddRef ();}
	~CCPtr () {Release ();}

	void Release () {
		if (! m_p)
			return;

		if (m_p->Release ())
			delete m_p;
		m_p = NULL;
	}

	CCPtr<T> & operator = (T * _p) {
		Release ();
		if (_p)
			m_p = _p;

		return * this;
	}
	CCPtr<T> & operator = (const CCPtr<T> & _other) {
		if (& _other == this)
			return * this;

		Release ();
		if (_other.m_p) {
			m_p = _other.m_p;
			m_p->AddRef ();
		}

		return * this;
	}

	const T * operator -> () const {return m_p;}
	      T * operator -> ()       {return m_p;}

	operator bool () const {return m_p != NULL;}
	bool operator ! () const {return m_p == NULL;}

	const T & data () const {return * m_p;}
	      T & data ()       {return * m_p;}
};

# endif // __CPtr_H_